home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 280_01 / find1.c < prev    next >
Text File  |  1989-01-11  |  6KB  |  307 lines

  1. /* [FIND1.C of JUGPDS Vol.46] */
  2. /*
  3. *****************************************************************
  4. *                                *
  5. *       Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  6. *            49-114 Kawauchi-Sanjuunin-machi        *
  7. *            Sendai, Miyagi 980                          *
  8. *            Phone: 0222-61-3219                *
  9. *                                *
  10. *       Modifird by Toshiya Oota   (JUG-CPM No.10)              *
  11. *                   Sakae ko-po 205                 *
  12. *            5-19-6 Hosoda                *
  13. *            Katusikaku Tokyo 124            *
  14. *                                *
  15. *        for MS-DOS Lattice C V3.1J & 80186/V20/V30    *
  16. *                                *
  17. *    Compiler Option: -ccu -k0(1) -ms -n -v -w        *
  18. *                                *
  19. *    Edited & tested by Y. Monma (JUG-CP/M Disk Editor)    *
  20. *            &  T. Ota   (JUG-CP/M Sub Disk Editor)    *
  21. *                                *
  22. *****************************************************************
  23. */
  24.  
  25. /* find1 - find patterns in text */
  26.  
  27. #include "stdio.h"
  28. #include "dos.h"
  29. #include "tools.h"
  30. #include "toolfunc.h"
  31.  
  32. #define    DEBUG        1
  33.  
  34. #define    YES        0
  35. #define    NO        -1
  36.  
  37. #define    NOT_CHAR    '!'
  38. #define    NOT        0x00800
  39. #define    NMASK        0x0FEFF
  40. #define    BOL_CHAR    '%'
  41. #define    BOL        0x00125
  42. #define    ANY_CHAR    '?'
  43. #define    ANY        0x0013F
  44. #define    EOL_CHAR    '$'
  45. #define    EOL        0x00124
  46. #define    PCLOSURE_CHAR    '+'
  47. #define    CLOSURE_CHAR    '*'
  48. #define    CLOSURE        0x04000
  49. #define    CMASK        0x0BFFF
  50. #define    CCL_CHAR    '['
  51. #define    CCL        0x02000
  52. #define    NCL        0x01000
  53. #define    ECL_CHAR    ']'
  54. #define    GROUP        '-'
  55. #define    UC        '\\'
  56.  
  57. int    np;
  58. int    spat[16][64];
  59.  
  60. void makpat0(),getccl0();
  61. char esc0();
  62.  
  63. void main(argc, argv)
  64. int    argc;
  65. char *argv[];
  66.  
  67. {
  68. char    line[MAXLINE];
  69. int    pat[MAXPAT];
  70.  
  71. #ifdef    DEBUG
  72. int    i, j;
  73. #endif
  74.  
  75.     np = 0;
  76.     if (argc < 2) {
  77.     fprintf(stderr, "FND992 Usage: find1 pattern <infile >outfile\n");
  78.     exit();
  79.     }
  80.     makpat0(pat, argv[1]);
  81.  
  82. #ifdef    DEBUG
  83.  
  84.     printf("PAT[ ]");
  85.     for (j = 0; pat[j] != '\0'; j++)
  86.     printf("\nFND802 pat[%3d]=%04x", j, pat[j]);
  87.     putchar('\n');
  88.     for (i = 0; i < np; i++) {
  89.     printf("\nFND804 PAT[%1d]", i);
  90.     for (j = 0; spat[i][j] != '\0'; j++)
  91.         printf("\nFND806 spat[%3d][%3d] = %04x", i, j, spat[i][j]);
  92.     putchar('\n');
  93.     }
  94. #endif
  95.  
  96.     while (getline(line, MAXLINE) > 0)
  97.     if (match(line, pat) >= 0)
  98.         printf("%s", line);
  99. }
  100.  
  101. /* makpat0 -make pattern from arg(from), terminates atdelim */
  102. void makpat0(s, t)
  103. int    *s;
  104. char    *t;
  105.  
  106. {
  107. register    char    *tt;
  108.  
  109.     tt = t;
  110.     if (*t == BOL_CHAR) {
  111.     *s++ = BOL;
  112.     t++;
  113.     }
  114.     for (; *t != '\0'; t++) {
  115.     if (*t == ANY_CHAR)
  116.         *s++ = ANY;
  117.     else if (*t == EOL_CHAR && *(t+1) == '\0')
  118.         *s++ = EOL;
  119.     else if (*t == CLOSURE_CHAR && t > tt)
  120.         *(s-1) |= CLOSURE;
  121.     else if (*t == PCLOSURE_CHAR && t > tt)
  122.         *s++ = *(s-1) | CLOSURE;
  123.     else if (*t == CCL_CHAR && *(t+1) != '\0')
  124.         getccl0(np++,&s,&t);
  125.     else if (*t == NOT_CHAR && *t != '\0') {
  126.         t++;
  127.         *s++ = esc0(&t) | NOT;
  128.     }
  129.     else
  130.         *s++ = esc0(&t) ;
  131.     }
  132.     *s = '\0';
  133. }
  134.  
  135. /* getccl0 - expand char class at arg(i) into pat(j) */
  136. void getccl0(np,x,y)
  137. register int  **x;
  138. register char **y;
  139.  
  140. {
  141. char    ss, st, ch;
  142. int    i;
  143. #define    s    (*x)
  144. #define    t    (*y)
  145.  
  146.     t++;
  147.     if (*t == NOT_CHAR) {
  148.     *s++ = NCL + np;
  149.     t++;
  150.     }
  151.     else
  152.     *s++ = CCL + np;
  153.     for (i = 0; *t != ECL_CHAR && *t != '\0'; i++, t++) {
  154.     if (*t != GROUP)
  155.         spat[np][i] = esc0(y);
  156.     else {
  157.         t++;
  158.         ss = esc0(y);
  159.         st = spat[np][i-1];
  160.         if ((isdigit(st) && isdigit(ss) ||
  161.             islower(st) && islower(ss) ||
  162.             isupper(st) && isupper(ss)) &&
  163.             st < ss) {
  164.         i--;
  165.         for (ch = st; ch <= ss; ch++)
  166.         spat[np][i++] = ch;
  167.         i--;
  168.         }
  169.         else {
  170.         spat[np][i++] = GROUP;
  171.         spat[np][i]   = ss;
  172.         }
  173.     }
  174.     }
  175.     spat[np][i] = '\0';
  176.     t--;
  177.     if (*t != '\0')
  178.     t++;
  179.  
  180. #undef t
  181. #undef s
  182. }
  183.  
  184. /* esc0 - map aray(i) into escaped character if appropriate */
  185. char esc0(x)
  186. register char **x;
  187. {
  188. #define    t    (*x)
  189.  
  190.     if (*t == '@' && *(t+1) != '\0')
  191.     switch (*++t) {
  192.         case 'n' :
  193.         case 'N' :    return ('\n');
  194.         case 's' :
  195.         case 'S' :    return (' ');
  196.         case 't' :
  197.         case 'T' :    return ('\t');
  198.         default  :    return (*t);
  199.     }
  200.     else if (*t == UC && *(t+1) != '\0')
  201.     return (char) toupper(*++t);
  202.     else
  203.     return (char) tolower(*t);
  204.  
  205. #undef    s
  206. }
  207.  
  208. getline(s,lim)
  209. char *s;
  210.  
  211. {
  212. register int    c;
  213. register char    *p;
  214.  
  215.     p = s;
  216.     while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
  217.     *p++ = c;
  218.     if (c == '\n')
  219.         *p++ = '\n';
  220.     *p = '\0';
  221.     return (p-s);
  222. }
  223.  
  224. /* match - find character anywhere on line */
  225. match(text,pattarn)
  226. int    *pattarn;
  227. char    *text;
  228.  
  229. {
  230. int    i;
  231. char    *ss;
  232.  
  233.     for (ss = text; *text != '\0'; text++) {
  234.     if ((i = amatch(text,pattarn,ss)) >= 0)
  235.         return i;
  236.     }
  237.     return -1;
  238. }
  239.  
  240. /* amatch (non-recursive) - look for match starting at lin(from) */
  241. amatch(text,pattarn,tp)
  242. register char *text, *tp;
  243. register int  *pattarn;
  244. {
  245. char    *temp, *tmp2;
  246. int    k, *newpat;
  247.  
  248.     for (temp = text; *pattarn != '\0';pattarn++) {
  249.     if ((*pattarn & CLOSURE) == CLOSURE) {
  250.         for (tmp2 = temp; *tmp2 != '\0';) {
  251.         if (omatch(&tmp2,*pattarn & CMASK,tp) == NO)
  252.             break;
  253.         }
  254.         for (newpat = pattarn+1; tmp2 >= temp; tmp2--) {
  255.         if ((k = amatch(tmp2,newpat,tp)) >= 0)
  256.             break;
  257.         }
  258.         temp = tmp2 + k;
  259.         break;
  260.     }
  261.     else if (omatch(&temp,*pattarn,tp) == NO)
  262.         return -1;
  263.     }
  264.     return (temp-text);
  265. }
  266.  
  267. /* omatch - try to match a single pattern at pat(j */
  268. omatch(ln, pattarn, s)
  269. register char **ln, *s;
  270. register int  pattarn;
  271. {
  272. int    retv;
  273.  
  274.     if (**ln == '\0')
  275.     retv =  (NO);
  276.     else if (pattarn == ANY && **ln != '\n') {
  277.     (*ln)++;
  278.     retv =  (YES);
  279.     }
  280.     else if (pattarn == BOL && *ln == s)
  281.     retv =  (YES);
  282.     else if (pattarn == EOL && **ln == '\n')
  283.     retv =  (YES);
  284.     else if ((pattarn & NOT) == NOT)
  285.     retv =  (*(*ln)++ == (pattarn & NMASK) ? NO : YES);
  286.     else if ((pattarn & CCL) == CCL)
  287.     retv = iindex(spat[pattarn & 255],*(*ln)++);
  288.     else if ((pattarn & NCL) == NCL)
  289.     retv=(iindex(spat[pattarn & 255],*(*ln)++) == YES ? NO : YES);
  290.     else
  291.     retv =  (*(*ln)++ == pattarn ? YES : NO);
  292.     return retv;
  293. }
  294.  
  295.  
  296. iindex(pat,c)
  297. register int *pat;
  298. register char c;
  299.  
  300. {
  301.     pat--;
  302.     while (*++pat)
  303.     if (*pat == c)
  304.         return YES;
  305.     return NO;
  306. }
  307.